﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.SqlServer.Dts.Pipeline.Design;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using com.sap.mw.jco;
using Microsoft.SqlServer.Dts.Runtime;

namespace SSISForSAPComponents
{
    public partial class SAPDataSourceEditUi : Form
    {
        private string _rfcname;
        private List<System.Data.DataTable> _staticDataTable;
        List<DataTable> _PipelineTableMapings;
        private com.sap.mw.jco.JCO.Client _conn;
        private JCO.Function _function;
        IDTSComponentMetaData90 metaData90;
        List<TableType> outputTableType;
        List<TableType> ImportTableType;
        List<ParameterValue> ImportParameterValue;
        List<ParameterValue> ExportParameterValue;
        System.Collections.Generic.Dictionary<string, DataTable> importStructureValue = new Dictionary<string, DataTable>();
        System.Collections.Generic.Dictionary<string, DataTable> exportStructureValue = new Dictionary<string, DataTable>();
        Microsoft.SqlServer.Dts.Runtime.Variables _variables;
        public bool DataChanged;
        public SAPDataSourceEditUi()
        {
            InitializeComponent();
        }
        public SAPDataSourceEditUi(string rfcName, com.sap.mw.jco.JCO.Client conn, IDTSComponentMetaData90 metaData, Microsoft.SqlServer.Dts.Runtime.Variables variables)
            : this()
        {
            this._variables = variables;
            _rfcname = rfcName;
            this.txtName.Text = rfcName;
            this._conn = conn;

            this.metaData90 = metaData;

            string xml = this.GetPropertyValue("StaticTableValue") == null ? "" : this.GetPropertyValue("StaticTableValue") as String;
            System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(List<System.Data.DataTable>));
            System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(xml));
            if (ms.Length > 0)
            {

                this._staticDataTable = ser.Deserialize(ms) as List<System.Data.DataTable>;
            }

            xml = this.GetPropertyValue("OuterTableType") == null ? "" : this.GetPropertyValue("OuterTableType") as String;
            ser = new System.Xml.Serialization.XmlSerializer(typeof(List<TableType>));
            ms = new System.IO.MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(xml));
            if (ms.Length > 0)
            {

                this.outputTableType = ser.Deserialize(ms) as List<TableType>;
            }

            xml = this.GetPropertyValue("ImportTableType") == null ? "" : this.GetPropertyValue("ImportTableType") as String;
            ser = new System.Xml.Serialization.XmlSerializer(typeof(List<TableType>));
            ms = new System.IO.MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(xml));
            if (ms.Length > 0)
            {

                this.ImportTableType = ser.Deserialize(ms) as List<TableType>;
            }

            xml = this.GetPropertyValue("PipelineTableValue") == null ? "" : this.GetPropertyValue("PipelineTableValue") as String;
            ser = new System.Xml.Serialization.XmlSerializer(typeof(List<DataTable>));
            ms = new System.IO.MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(xml));
            if (ms.Length > 0)
            {

                this._PipelineTableMapings = ser.Deserialize(ms) as List<DataTable>;
            }

            xml = this.GetPropertyValue("ImportParameterValue") == null ? "" : this.GetPropertyValue("ImportParameterValue") as String;
            ser = new System.Xml.Serialization.XmlSerializer(typeof(List<ParameterValue>));
            ms = new System.IO.MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(xml));
            if (ms.Length > 0)
            {

                this.ImportParameterValue = ser.Deserialize(ms) as List<ParameterValue>;
            }

            xml = this.GetPropertyValue("ExportParameterValue") == null ? "" : this.GetPropertyValue("ExportParameterValue") as String;
            ser = new System.Xml.Serialization.XmlSerializer(typeof(List<ParameterValue>));
            ms = new System.IO.MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(xml));
            if (ms.Length > 0)
            {

                this.ExportParameterValue = ser.Deserialize(ms) as List<ParameterValue>;
            }

            //ImportTableType = this.GetPropertyValue("ImportTableType") as System.Collections.Generic.Dictionary<string, string>;

            if (this._staticDataTable == null)
            {
                this._staticDataTable = new List<DataTable>();
            }
            if (outputTableType == null)
            {
                outputTableType = new List<TableType>();
            }
            if (ImportTableType == null)
            {
                ImportTableType = new List<TableType>();
            }
            if (_PipelineTableMapings == null)
            {
                _PipelineTableMapings = new List<DataTable>();
            }
            if (ImportParameterValue == null)
            {
                ImportParameterValue = new List<ParameterValue>();
            }
            if (ExportParameterValue == null)
            {
                ExportParameterValue = new List<ParameterValue>();
            }
            foreach (ParameterValue value in ImportParameterValue)
            {
                if (value.ParameterType.Equals("B"))
                {
                    this.importStructureValue.Add(value.Name, value.StructureValue);
                }
            }
            foreach (ParameterValue value in ExportParameterValue)
            {
                if (value.ParameterType.Equals("B"))
                {
                    this.exportStructureValue.Add(value.Name, value.StructureValue);
                }
            }
        }

        private void SAPDataSourceEditUi_Load(object sender, EventArgs e)
        {
            if (!_rfcname.Equals(String.Empty))
            {
                LoadmetaData();
            }

        }
        /// <summary>
        /// 加载元数据
        /// </summary>
        private void LoadmetaData()
        {
            this._conn.connect();
            com.sap.mw.jco.JCO.Repository repostory = new com.sap.mw.jco.JCO.Repository("VSoft", this._conn);
            com.sap.mw.jco.IFunctionTemplate ft = ((_rfcname == null || _rfcname.Equals(string.Empty)) ? null : repostory.getFunctionTemplate(_rfcname));
            this._conn.disconnect();

            if (ft != null)
            {
                _function = new JCO.Function(ft);
                this.dataGridViewImports.Rows.Clear();
                this.dataGridViewTable.Rows.Clear();
                this.dataGridViewExports.Rows.Clear();

                #region Table部分


                for (int i = 0; i < _function.getTableParameterList().getFieldCount(); i++)
                {
                    int index = this.dataGridViewTable.Rows.Add();
                    string importvalue = "Skip";//输入类型
                    if (ImportTableType != null && ImportTableType.Count > 0)//查找输入配置
                    {
                        foreach (TableType type in this.ImportTableType)
                        {
                            if (type.Tablename.Equals(_function.getTableParameterList().getName(i)))
                            {
                                importvalue = type.Type;
                            }
                        }
                    }
                    this.dataGridViewTable.Rows[index].Cells[0].Value = _function.getTableParameterList().getName(i);
                    this.dataGridViewTable.Rows[index].Cells[1].Value = importvalue;


                    this.dataGridViewTable.Rows[index].Cells[2].Value = "Edit";
                    string outputvalue = "Skip";//输出类型
                    if (outputTableType != null && outputTableType.Count > 0)//查找输出配置
                    {
                        foreach (TableType type in this.outputTableType)
                        {
                            if (type.Tablename.Equals(_function.getTableParameterList().getName(i)))
                            {
                                outputvalue = type.Type;
                            }
                        }
                    }
                    this.dataGridViewTable.Rows[index].Cells[3].Value = outputvalue;


                    //this.dataGridViewTable.Rows.Add(dr);   
                }
                #endregion
                #region Import部分

                if (_function.getImportParameterList() != null)
                {

                    for (int i = 0; i < _function.getImportParameterList().getFieldCount(); i++)
                    {

                        int index = this.dataGridViewImports.Rows.Add();
                        this.dataGridViewImports.Rows[index].Cells[0].Value = _function.getImportParameterList().getName(i);
                        if (_function.getImportParameterList().isStructure(i))
                        {
                            this.dataGridViewImports.Rows[index].Cells[2].Value = "Edit";
                            this.dataGridViewImports.Rows[index].Cells[1].ReadOnly = true;
                        }
                        else
                        {
                            this.dataGridViewImports.Rows[index].Cells[2].Value = "";
                            this.dataGridViewImports.Rows[index].Cells[1].ReadOnly = false;
                            //设置输入参数
                            foreach (ParameterValue value in this.ImportParameterValue)
                            {
                                if (value.Name.Equals(_function.getImportParameterList().getName(i)))
                                {
                                    this.dataGridViewImports.Rows[index].Cells[1].Value = value.Value;
                                }
                            }
                        }

                    }
                }
                #endregion
                #region Export部分

                if (_function.getExportParameterList() != null)
                {

                    ExportVariable.Items.Clear();
                    ExportVariable.Items.Add("<Null>");
                    foreach (Variable variable in _variables)
                    {
                        ExportVariable.Items.Add("@" + variable.Name);
                    }
                    for (int i = 0; i < _function.getExportParameterList().getFieldCount(); i++)
                    {

                        int index = this.dataGridViewExports.Rows.Add();
                        this.dataGridViewExports.Rows[index].Cells[0].Value = _function.getExportParameterList().getName(i);
                        if (_function.getExportParameterList().isStructure(i))
                        {
                            this.dataGridViewExports.Rows[index].Cells[2].Value = "Edit";
                            this.dataGridViewExports.Rows[index].Cells[1].ReadOnly = true;
                        }
                        else
                        {
                            this.dataGridViewExports.Rows[index].Cells[2].Value = "";
                            this.dataGridViewExports.Rows[index].Cells[1].ReadOnly = false;
                            //设置输出参数
                            foreach (ParameterValue value in this.ExportParameterValue)
                            {
                                if (value.Name.Equals(_function.getExportParameterList().getName(i)))
                                {
                                    this.dataGridViewExports.Rows[index].Cells[1].Value = value.Value;
                                }
                            }
                        }

                    }
                }
                #endregion
            }
            else
            {
                MessageBox.Show("No found The Rfc '" + _rfcname + "'", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }

        }

        private void btnCheck_Click(object sender, EventArgs e)
        {
            this._rfcname = this.txtName.Text;
            _staticDataTable.Clear();
            this._PipelineTableMapings.Clear();
            this.outputTableType.Clear();
            this.ImportTableType.Clear();
            LoadmetaData();
        }

        private void btnOk_Click(object sender, EventArgs e)
        {

            try
            {
                this.outputTableType.Clear();
                this.ImportTableType.Clear();
                this.ImportParameterValue.Clear();
                this.ExportParameterValue.Clear();
                //List<System.Data.DataTable> tables = new List<DataTable>();
                foreach (DataGridViewRow dr in this.dataGridViewTable.Rows)
                {
                    this.outputTableType.Add(new TableType(dr.Cells[0].Value.ToString(), dr.Cells[3].Value.ToString()));
                    this.ImportTableType.Add(new TableType(dr.Cells[0].Value.ToString(), dr.Cells[1].Value.ToString()));
                }
                //配置输入参数
                foreach (DataGridViewRow dr in this.dataGridViewImports.Rows)
                {

                    ParameterValue value = new ParameterValue();
                    value.Name = dr.Cells[0].Value.ToString();
                    if (dr.Cells[2].Value.ToString().Equals(null) || dr.Cells[2].Value.ToString().Equals(""))
                    {
                        if (dr.Cells[1].Value != null)
                        {
                            value.ParameterType = "A";
                            value.Value = dr.Cells[1].Value.ToString();
                            if (dr.Cells[1].Value.ToString().IndexOf("@") == 0)
                            {
                                value.ValueType = "Variable";
                            }
                            else
                            {
                                value.ValueType = "Static";
                            }
                            this.ImportParameterValue.Add(value);
                        }
                    }
                    else
                    {
                        value.ParameterType = "B";
                        System.Data.DataTable table = new DataTable();
                        if (this.importStructureValue.TryGetValue(value.Name, out table))
                        {
                            value.StructureValue = table;
                            this.ImportParameterValue.Add(value);
                        }

                    }


                }
                //配置输出参数
                foreach (DataGridViewRow dr in this.dataGridViewExports.Rows)
                {

                    ParameterValue value = new ParameterValue();
                    value.Name = dr.Cells[0].Value.ToString();
                    if (dr.Cells[2].Value.ToString().Equals(null) || dr.Cells[2].Value.ToString().Equals(""))
                    {
                        if (dr.Cells[1].Value != null && !dr.Cells[1].Value.ToString().Equals("<Null>"))
                        {
                            value.ParameterType = "A";
                            value.Value = dr.Cells[1].Value.ToString();
                            if (dr.Cells[1].Value.ToString().IndexOf("@") == 0)
                            {
                                value.ValueType = "Variable";
                            }
                            else
                            {
                                value.ValueType = "Static";
                            }
                            this.ExportParameterValue.Add(value);
                        }
                    }
                    else
                    {
                        value.ParameterType = "B";
                        System.Data.DataTable table = new DataTable();
                        if (this.exportStructureValue.TryGetValue(value.Name, out table))
                        {
                            value.StructureValue = table;
                            this.ExportParameterValue.Add(value);
                        }


                    }


                }

                System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(List<System.Data.DataTable>));
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                ser.Serialize(ms, this._staticDataTable);
                byte[] bytes = ms.ToArray();
                string xml = System.Text.UTF8Encoding.UTF8.GetString(bytes);
                this.SetPropertyValue("StaticTableValue", xml);

                ser = new System.Xml.Serialization.XmlSerializer(typeof(List<TableType>));
                ms = new System.IO.MemoryStream();
                ser.Serialize(ms, this.outputTableType);
                bytes = ms.ToArray();
                xml = System.Text.UTF8Encoding.UTF8.GetString(bytes);
                this.SetPropertyValue("OuterTableType", xml);

                ser = new System.Xml.Serialization.XmlSerializer(typeof(List<TableType>));
                ms = new System.IO.MemoryStream();
                ser.Serialize(ms, this.ImportTableType);
                bytes = ms.ToArray();
                xml = System.Text.UTF8Encoding.UTF8.GetString(bytes);
                this.SetPropertyValue("ImportTableType", xml);
                this.SetPropertyValue("rfcMame", this._rfcname);


                ser = new System.Xml.Serialization.XmlSerializer(typeof(List<DataTable>));
                ms = new System.IO.MemoryStream();
                ser.Serialize(ms, this._PipelineTableMapings);
                bytes = ms.ToArray();
                xml = System.Text.UTF8Encoding.UTF8.GetString(bytes);
                this.SetPropertyValue("PipelineTableValue", xml);

                ser = new System.Xml.Serialization.XmlSerializer(typeof(List<ParameterValue>));
                ms = new System.IO.MemoryStream();
                ser.Serialize(ms, this.ImportParameterValue);
                bytes = ms.ToArray();
                xml = System.Text.UTF8Encoding.UTF8.GetString(bytes);
                this.SetPropertyValue("ImportParameterValue", xml);

                ser = new System.Xml.Serialization.XmlSerializer(typeof(List<ParameterValue>));
                ms = new System.IO.MemoryStream();
                ser.Serialize(ms, this.ExportParameterValue);
                bytes = ms.ToArray();
                xml = System.Text.UTF8Encoding.UTF8.GetString(bytes);
                this.SetPropertyValue("ExportParameterValue", xml);


                //this.SetPropertyValue("OuterTableType", this.outputTableType);
                //this.SetPropertyValue("ImportTableType", this.ImportTableType);

                //重设置输出
                SAPDataSource.StaticReinitializeMetaData(metaData90, outputTableType, this._conn, ImportTableType);
                //this._staticDataTable = this.GetPropertyValue("StaticTableValue") as List<System.Data.DataTable>;
                this.Close();
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
        }

        private void btnCanCel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        public void SetPropertyValue(string PropertyName, object Value)
        {

            for (int i = 0; i < this.metaData90.CustomPropertyCollection.Count; i++)
            {
                if (this.metaData90.CustomPropertyCollection[i].Name.Equals(PropertyName))
                {
                    this.DataChanged = true;
                    this.metaData90.CustomPropertyCollection[i].Value = Value;
                    break;
                }
            }

        }
        public object GetPropertyValue(string PropertyName)
        {
            for (int i = 0; i < this.metaData90.CustomPropertyCollection.Count; i++)
            {
                if (this.metaData90.CustomPropertyCollection[i].Name.Equals(PropertyName))
                {
                    return this.metaData90.CustomPropertyCollection[i].Value;
                }
            }
            return null;
        }

        private void dataGridViewTable_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

            try
            {
                if (e.ColumnIndex == 2)
                {
                    if (dataGridViewTable.Rows[e.RowIndex].Cells[1].Value.ToString().Equals("Skip"))
                    {
                        System.Windows.Forms.MessageBox.Show("If you want to edit or map this table, please set Input Type to 'Pipeline' or 'Static', not to 'Skip'.");
                    }
                    else
                    {
                        string tablename = dataGridViewTable.Rows[e.RowIndex].Cells[0].Value.ToString();
                        if (dataGridViewTable.Rows[e.RowIndex].Cells[1].Value.ToString().Equals("Static"))
                        {


                            System.Data.DataTable table = null;
                            foreach (DataTable itemTable in _staticDataTable)
                            {
                                if (itemTable.TableName.Equals(tablename))
                                {
                                    table = itemTable;
                                }
                            }

                            if (table == null)//表示未设置过的
                            {
                                table = Util.ConventSapTableToDataTable(this._function.getTableParameterList().getTable(tablename), tablename);
                                SapDataSourceStaticTableEdit tableedit = new SapDataSourceStaticTableEdit(table);
                                if (tableedit.ShowDialog() == DialogResult.OK)
                                {
                                    if (table.Rows.Count > 0)
                                    {
                                        _staticDataTable.Add(table);
                                    }
                                }
                            }
                            else //表示已经设置过的
                            {

                                SapDataSourceStaticTableEdit tableedit = new SapDataSourceStaticTableEdit(table);
                                if (tableedit.ShowDialog() == DialogResult.OK)
                                {

                                }
                            }
                        }
                        else if (dataGridViewTable.Rows[e.RowIndex].Cells[1].Value.ToString().Equals("Pipeline"))
                        {
                            IDTSInput90 input = null;
                            foreach (IDTSInput90 inputitem in this.metaData90.InputCollection)
                            {
                                if (inputitem.CustomPropertyCollection["SapTableName"].Value.ToString().Equals(tablename))
                                {
                                    input = inputitem;
                                }
                            }
                            if (input == null)
                                return;
                            DataTable table = new DataTable();
                            foreach (DataTable tableitem in this._PipelineTableMapings)
                            {
                                if (tableitem.TableName.Equals(tablename))
                                {
                                    table = tableitem;

                                }
                            }
                            if (table.Rows.Count <= 0)//表示未设置过
                            {
                                table.TableName = tablename;
                                table.Columns.Add("InputColumnName", typeof(System.String));
                                table.Columns.Add("OutputId", typeof(System.String));
                                JCO.Table saptable = this._function.getTableParameterList().getTable(tablename);
                                for (int i = 0; i < saptable.getFieldCount(); i++)
                                {

                                    DataRow dr = table.NewRow();
                                    dr["InputColumnName"] = saptable.getName(i);
                                    dr["OutputId"] = 0;
                                    table.Rows.Add(dr);


                                }
                                table.AcceptChanges();
                                SapDataSourcePipelineMapingEdit edit = new SapDataSourcePipelineMapingEdit(table, input);
                                if (edit.ShowDialog() == DialogResult.OK)
                                {
                                    this._PipelineTableMapings.Add(table);
                                }
                            }
                            else
                            {
                                SapDataSourcePipelineMapingEdit edit = new SapDataSourcePipelineMapingEdit(table, input);
                                if (edit.ShowDialog() == DialogResult.OK)
                                {
                                    //this._PipelineTableMapings.Add(table);
                                }
                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                
                throw ex;
            }

        }

        private void dataGridViewTable_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {

            //if (e.ColumnIndex == 1 && dataGridViewTable.Rows.Count>0)
            //{
            //    if (!dataGridViewTable.Rows[e.RowIndex].Cells[1].Value.Equals("Static"))//删除设置
            //    {
            //        string tablename = dataGridViewTable.Rows[e.RowIndex].Cells[0].Value.ToString();
            //        System.Data.DataTable table = null;
            //        foreach (DataTable itemTable in _staticDataTable)
            //        {
            //            if (itemTable.TableName.Equals(tablename))
            //            {
            //                table = itemTable;
            //            }
            //        }
            //        this._staticDataTable.Remove(table);
            //    }
            //}
        }

        private void dataGridViewImports_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.ColumnIndex == 2)
                {
                    if (this.dataGridViewImports.Rows[e.RowIndex].Cells[2].Value.ToString().Equals("Edit"))
                    {
                        DataTable table = new DataTable("test");
                        string name = this.dataGridViewImports.Rows[e.RowIndex].Cells[0].Value.ToString();
                        if (!this.importStructureValue.TryGetValue(name, out table))
                        {
                            table = new DataTable(name);
                            table.Columns.Add("Name", typeof(String));
                            table.Columns.Add("Value", typeof(String));
                            JCO.Structure structure = _function.getImportParameterList().getStructure(name);
                            for (int i = 0; i < structure.getFieldCount(); i++)
                            {
                                DataRow dr = table.NewRow();
                                dr["Name"] = structure.getName(i);
                                dr["Value"] = "";
                                table.Rows.Add(dr);
                            }
                            table.AcceptChanges();
                            ImportStructureEdit edit = new ImportStructureEdit(table);
                            if (edit.ShowDialog() == DialogResult.OK)
                            {
                                this.importStructureValue.Add(name, table);
                            }
                        }
                        else
                        {
                            ImportStructureEdit edit = new ImportStructureEdit(table);
                            if (edit.ShowDialog() == DialogResult.OK)
                            {

                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
        }

        private void dataGridViewExports_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.ColumnIndex == 2)
                {
                    if (this.dataGridViewExports.Rows[e.RowIndex].Cells[2].Value.ToString().Equals("Edit"))
                    {
                        DataTable table = new DataTable("test");
                        string name = this.dataGridViewExports.Rows[e.RowIndex].Cells[0].Value.ToString();
                        if (!this.exportStructureValue.TryGetValue(name, out table))
                        {
                            table = new DataTable(name);
                            table.Columns.Add("Name", typeof(String));
                            table.Columns.Add("Value", typeof(String));
                            JCO.Structure structure = _function.getImportParameterList().getStructure(name);
                            for (int i = 0; i < structure.getFieldCount(); i++)
                            {
                                DataRow dr = table.NewRow();
                                dr["Name"] = structure.getName(i);
                                dr["Value"] = "";
                                table.Rows.Add(dr);
                            }
                            table.AcceptChanges();
                            ExportStructureEdit edit = new ExportStructureEdit(table, this._variables);
                            if (edit.ShowDialog() == DialogResult.OK)
                            {
                                this.exportStructureValue.Add(name, table);
                            }
                        }
                        else
                        {
                            ExportStructureEdit edit = new ExportStructureEdit(table, this._variables);
                            if (edit.ShowDialog() == DialogResult.OK)
                            {

                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                
                throw;
            }
        }

    }
}
